﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Common
{
    public enum Feature { NUM_SENONES, NUM_GAUSSIANS_PER_STATE, NUM_STREAMS };
    /// <summary>
    /// Used to pool shared objects in the acoustic model
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Pool<T>
    {
        ///public enum Feature { NUM_SENONES, NUM_GAUSSIANS_PER_STATE, NUM_STREAMS }

        private String name;
        public  List<T> pool;
        private Dictionary<Feature, int> features = new Dictionary<Feature, int>();

        /**
        /// Creates a new pool.
         *
        /// @param name the name of the pool
         */
        public Pool(String name) 
        {
            this.name = name;
            pool = new List<T>();
        }

        /**
        /// Returns the pool's name.
         *
        /// @return the pool name
         */
        public String getName() 
        {
            return name;
        }

        /**
        /// Returns the object with the given ID from the pool.
         *
        /// @param id the id of the object
        /// @return the object
        /// @throws IndexOutOfBoundsException if the ID is out of range
         */
        public T get(int id) 
        {
            return pool[id];
        }

        /**
        /// Returns the ID of a given object from the pool.
         *
        /// @param object the object
        /// @return the index
         */
        public int indexOf(T _object) 
        {
            return pool.IndexOf(_object);
        }

        /**
        /// Places the given object in the pool.
         *
        /// @param id a unique ID for this object
        /// @param o  the object to add to the pool
         */
        public void put(int id, T o) 
        {
            if (id == pool.Count) 
            {
                pool.Add(o);
            } 
            else 
            {
                pool[id] =  o;
            }
        }

        /**
        /// Retrieves the size of the pool.
         *
        /// @return the size of the pool
         */
        public int size() 
        {
            return pool.Count;
        }

        /**
        /// Dump information on this pool to the given logger.
         *
        /// @param logger the logger to send the info to
         */
        public void logInfo() 
        {
            Trace.WriteLine("Pool " + name + " Entries: " + size());
        }

        /**
        /// Sets a feature for this pool.
         *
        /// @param feature feature to set
        /// @param value the value for the feature
         */
        public void setFeature(Feature feature, int value) 
        {
            if (features.ContainsKey(feature))
                features[feature] = value;
            else
                features.Add(feature, value);
        }

        /**
        /// Retrieves a feature from this pool.
         *
        /// @param feature feature to get
        /// @param defaultValue the defaultValue for the pool
        /// @return the value for the feature
         */
        public int getFeature(Feature feature, int defaultValue) 
        {
            int val = features[feature];
            return val == null ? defaultValue : val;
        }
    }
}
